package cqrtplm.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.pdm.doc.vo.DocDetails;
import com.hustcad.plm.pdm.ec.module.dto.ECObjData;
import com.hustcad.plm.pdm.file.service.TyplmFileHandleService;
import com.hustcad.plm.pdm.filevault.model.vo.FileDataVO;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChgFormView;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.flowbusiness.model.entity.WorkFlowObjectPackage;
import com.hustcad.plm.pdm.iba.mapper.TyplmBooleanDefMapper;
import com.hustcad.plm.pdm.iba.mapper.TyplmFloatDefMapper;
import com.hustcad.plm.pdm.iba.mapper.TyplmStringDefMapper;
import com.hustcad.plm.pdm.iba.model.dto.SaveObjIBADTO;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.partbom.dto.ChildPartsFiltersDTO;
import com.hustcad.plm.pdm.partbom.dto.ExpandBomTreeByFilterDTO;
import com.hustcad.plm.pdm.partbom.dto.PartBomTree;
import com.hustcad.plm.pdm.partbom.service.TyplmPartBomService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartRelObjectService;
import com.hustcad.plm.pdm.partbom.service.TyplmPartService;
import com.hustcad.plm.pdm.partbom.vo.PartBomTreeByFilterVO;
import com.hustcad.plm.pdm.partbom.vo.TyPartAllVO;
import com.hustcad.plm.pdm.partbom.vo.usagecount.PartUsageCountVO;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainerView;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.lark.oapi.okhttp.*;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.dto.constraint.IbaDTO;
import com.ty.basic.entity.CTyEntityBaseDO;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.attribute.BooleanDefDO;
import com.ty.basic.entity.attribute.FloatDefDO;
import com.ty.basic.entity.attribute.StringDefDO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.vo.AttributeVO;
import cqrtplm.common.CommonService;
import cqrtplm.dto.DrawingDetailsDTO;
import cqrtplm.dto.SendDrawingDTO;
import cqrtplm.mapper.CADDocumentMapper;
import cqrtplm.mapper.RTPartMapper;
import cqrtplm.service.SrmIntegrityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SrmIntegrityServiceImpl implements SrmIntegrityService {
    @Resource
    private CommonService commonService;
    @Resource
    private TyplmPartRelObjectService typlmPartRelObjectService;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private CADDocumentMapper cadDocumentMapper;
    @Resource
    private TyplmFileHandleService typlmFileHandleService;
    @Resource
    private RTPartMapper rtPartMapper;
    @Resource
    private TyplmWorkFlowContainerService typlmWorkFlowContainerService;
    @Resource
    private TyplmPartService typlmPartService;
    @Resource
    private TyplmPartBomService typlmPartBomService;
    @Resource
    private TyplmStringDefMapper typlmStringDefMapper;
    @Resource
    private TyplmBooleanDefMapper typlmBooleanDefMapper;
    @Resource
    private TyplmFloatDefMapper typlmFloatDefMapper;

    @Override
    public void sendCadFile(BigInteger workFlowContainerId) {
        List<IdentifierEntity> flowObjEntityList = commonService.getFlowObjListByWorkFlowContainer(workFlowContainerId);
        List<BigInteger> cadDocOidList = flowObjEntityList.stream()
                .filter(identifierEntity -> TableTypeConstrant.TY_CADDOC_OTYPE.equals(identifierEntity.getOtype()))
                .map(IdentifierEntity::getOid)
                .collect(Collectors.toList());
        Map<String, List<AttributeVO>> attrValueByOidAndKeys = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(cadDocOidList,
                TableTypeConstrant.TY_CADDOC_OTYPE,
                Collections.singletonList("BusinessVersion"));
        // 更新 业务版本，业务版本升版
        List<SaveObjIBADTO> objWithIbaList = new ArrayList<>();
        for (Map.Entry<String, List<AttributeVO>> entry : attrValueByOidAndKeys.entrySet()) {
            String key = entry.getKey();
            List<AttributeVO> value = entry.getValue();
            if (CollUtil.isNotEmpty(value)) {
                IbaDTO ibaDTO = new IbaDTO();
                SaveObjIBADTO dto = new SaveObjIBADTO();
                ibaDTO.setKey("BusinessVersion");
                ibaDTO.setValue(getNextVersion(value.get(0).getAttributeValue()));
                dto.setObjIbaList(Collections.singletonList(ibaDTO));
                dto.setCTyEntityBaseDO(new CTyEntityBaseDO(new BigInteger(key), TableTypeConstrant.TY_CADDOC_OTYPE));
                objWithIbaList.add(dto);
            }
        }
        typlmAttributeValueService.batchSaveIBAByObjList(objWithIbaList, false);

        //根据cadDocOidList 查询，编码相同的最新x-t外发文档对象
        List<IdentifierEntity> docEntityList = cadDocumentMapper.queryDocIdByCadId(cadDocOidList, "X-T外发");
        //根据docOid 获取最新电子文件
        Map<IdentifierEntity, List<FileDataVO>> docMap = typlmFileHandleService.batchGetFileListByEntity(docEntityList);
        Collection<List<FileDataVO>> values = docMap.values();

    }


    private String getNextVersion(String currentVersion) {
        if (currentVersion == null || !currentVersion.startsWith("V")) {
            return currentVersion; // 如果不是以 V 开头，返回原值
        }
        try {
            int versionNumber = Integer.parseInt(currentVersion.substring(1));
            return "V" + (versionNumber + 1);
        } catch (NumberFormatException e) {
            log.error("Invalid version format: {}", currentVersion, e);
            return currentVersion; // 如果格式不正确，返回原值
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDrawingDownloadStatus(List<String> drawingCode) {
        List<PartDO> partDOS = rtPartMapper.queryLatestPartByNumberList(drawingCode, "");
        if (CollUtil.isEmpty(partDOS)) {
            return;
        }
        List<SaveObjIBADTO> objWithIbaList = new ArrayList<>();
        for (PartDO partDO : partDOS) {
            IbaDTO ibaDTO = new IbaDTO();
            SaveObjIBADTO dto = new SaveObjIBADTO();
            ibaDTO.setKey("srmDrawing");
            ibaDTO.setValue("是");
            dto.setObjIbaList(Collections.singletonList(ibaDTO));
            dto.setCTyEntityBaseDO(new CTyEntityBaseDO(partDO.getOid(), partDO.getOtype()));
            objWithIbaList.add(dto);
        }
        typlmAttributeValueService.batchSaveIBAByObjList(objWithIbaList, false);
    }

    @Override
    public void sendDrawingToSrm(BigInteger workFlowContainerId, String type) {
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(workFlowContainerId);
        List<SendDrawingDTO> sendDrawingDTOList = new ArrayList<>();
        if ((workFlowContainerView instanceof WorkFlowObjectPackage)) {
            log.info("当前流程属于普通流程");
            WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
            String code = workFlowObjectPackage.getCode();
            LocalDate currentDate = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String formattedDate = currentDate.format(formatter);
            String filePath = "/drawing/" + formattedDate + "/" + code + "/";
            List<FlowObject> flowObjectList = workFlowObjectPackage.getFlowObjectList();
            if (CollUtil.isEmpty(flowObjectList)) {
                return;
            }
            List<FlowObject> newFlowObjectList = flowObjectList.stream().filter(
                            identifierEntity -> TableTypeConstrant.TY_PART_OTYPE.equals(identifierEntity.getRefObjectOtype()))
                    .collect(Collectors.toList());
            for (FlowObject flowObject : newFlowObjectList) {
                List<PartBomTree> partBomTreeList = commonService.queryChildPartsNoIba(
                        flowObject.getObjectNumber(),
                        String.valueOf(flowObject.getRefObjectOid()),
                        "Design", true,
                        null, "N", true).getPartBomTreeList();
                PartBomTree partBomTree = partBomTreeList.get(0);
                SendDrawingDTO sendDrawingDTO = new SendDrawingDTO();

                downloadDrawingAndGetDrawingInfo(partBomTree, sendDrawingDTO, filePath, type);
                sendDrawingDTO.setPushType(type);
                sendDrawingDTOList.add(sendDrawingDTO);
            }
        } else if (workFlowContainerView instanceof FlowChgFormView) {
            log.info("当前流程属于变更流程");
            FlowChgFormView flowChgFormView = (FlowChgFormView) workFlowContainerView;
            String code = workFlowContainerView.getCode();
            LocalDate currentDate = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String formattedDate = currentDate.format(formatter);
            String filePath = "/drawing/" + formattedDate + "/" + code + "/";
            // 检查 getChgFormVO 是否为 null
            if (flowChgFormView.getChgFormVO() != null) {
                List<ECObjData> flowObjectList = flowChgFormView.getChgFormVO().getEcAffectVOS();
                for (ECObjData ecObjData : flowObjectList) {
                    String viewName = ecObjData.getViewName();
                    String typeDefName = ecObjData.getTypeDefName();
                    if ("EBOM号".equals(typeDefName) || "图样代号".equals(typeDefName)|| "标准件".equals(typeDefName)) {
                        List<PartBomTree> partBomTreeList = commonService.queryChildPartsNoIba(
                                ecObjData.getObjectNumber(),
                                String.valueOf(ecObjData.getOid()),
                                "Design", true,
                                null, "N", true).getPartBomTreeList();
                        PartBomTree partBomTree = partBomTreeList.get(0);
                        SendDrawingDTO sendDrawingDTO = new SendDrawingDTO();

                        downloadDrawingAndGetDrawingInfo(partBomTree, sendDrawingDTO, filePath, type);
                        sendDrawingDTOList.add(sendDrawingDTO);
                    }
                }
            }
        }
        if (CollUtil.isNotEmpty(sendDrawingDTOList)) {
            JSONObject data = new JSONObject();
            data.put("trans", "Graph-ToDo");
            data.put("list", sendDrawingDTOList);
            String json = JSONArray.toJSONString(data);
            log.info("===========提示信息============> 发送图纸信息为：{}", json);
            sendDrawingInfoToSrm(json);
        }
    }

    private void sendDrawingInfoToSrm(String json) {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, json);
        Request request = new Request.Builder()
                .url("http://192.168.102.40/rt1j/WebAPI/PLM")
                .method("POST", body)
                .addHeader("appID", "jnC6xaa1PYZnFGDb")
                .addHeader("tokenKey", "ZbmHtZ9PwSwKzk4Z41HKxxpke4t5Frjy")
                .addHeader("Content-Type", "application/json")
                .build();
        try {
            Response response = client.newCall(request).execute();
            log.info("===========提示信息============> 获取图纸信息成功：{}", response.body().string());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void downloadDrawingAndGetDrawingInfo(PartBomTree partBomTree, SendDrawingDTO sendDrawingDTO, String filePath, String type) {
        List<DocDetails> docDetails = this.typlmPartRelObjectService.queryPartRelatedDocInfo(new BigInteger(partBomTree.getPartoid()));
        sendDrawingDTO.setPartNumber(partBomTree.getObjectNumber());
        sendDrawingDTO.setOid(partBomTree.getPartoid());
        sendDrawingDTO.setName(partBomTree.getName());
        List<DrawingDetailsDTO> drawingDetails = sendDrawingDTO.getDrawingDetails();
        for (DocDetails docDetail : docDetails) {
            log.info("===========提示信息============> 获取图纸信息开始");
            String cadType = docDetail.getCadType();
            if (cadType.contains("二维图纸")) {
                Map<String, List<String>> ibaAttributeMap = docDetail.getIbaAttributeMap();
                DrawingDetailsDTO drawingDetailsDTO = new DrawingDetailsDTO();
                drawingDetailsDTO.setDrawingCode(docDetail.getNumber());
                drawingDetailsDTO.setDrawingName(docDetail.getName());
                drawingDetailsDTO.setExclusiveSupplier(ibaAttributeMap != null && ibaAttributeMap.containsKey("ExclusiveSupplier") ? ibaAttributeMap.get("ExclusiveSupplier").get(0) : "");
                drawingDetailsDTO.setDrawingReleaseStage(ibaAttributeMap != null && ibaAttributeMap.containsKey("Stage") ? ibaAttributeMap.get("Stage").get(0) : "");
                drawingDetailsDTO.setImpInfo("");
                drawingDetailsDTO.setCreateDate(docDetail.getCreationTime());
                drawingDetailsDTO.setLastModifiedDate(docDetail.getModifyTime());
                drawingDetailsDTO.setCreateBy(docDetail.getCreatorFullName());
                drawingDetailsDTO.setUpdateBy(docDetail.getModifierFullName());
                drawingDetailsDTO.setVersion(docDetail.getVersion());

                drawingDetailsDTO.setTrans("Graph-ToDo");
                FileDataVO fileDataVO = docDetail.getPrimaryFileList().get(0);
                String url = commonService.downloadFileToFtp(new BigInteger(fileDataVO.getFileID()), filePath);
                drawingDetailsDTO.setDrawingFileUrl(url);
                drawingDetails.add(drawingDetailsDTO);
            }
        }
        HashSet<PartBomTree> children = partBomTree.getChildren();
        if (CollUtil.isNotEmpty(children)) {
            for (PartBomTree child : children) {
                SendDrawingDTO childSendDrawingDTO = new SendDrawingDTO();
                downloadDrawingAndGetDrawingInfo(child, childSendDrawingDTO, filePath, type);
                sendDrawingDTO.getChild().add(childSendDrawingDTO);
            }
        }
    }

    @Override
    public List<PartBomTree> queryParentPartInfo(List<String> partNumberList) {
        List<PartDO> partDOS = rtPartMapper.queryLatestPartByNumberList(partNumberList, "");
        if (CollUtil.isEmpty(partDOS)) {
            return Collections.emptyList();
        }
        Map<String, String> ibaAttrList = getIbaAttrList();
        List<PartBomTree> treeList = new ArrayList<>();
        for (PartDO partDO : partDOS) {
            BigInteger oid = partDO.getOid();
            getPartBomTreeInfo(oid, ibaAttrList, treeList);
        }
        return treeList;
    }

    private void getPartBomTreeInfo(BigInteger oid, Map<String, String> ibaAttrList, List<PartBomTree> treeList) {
        Map<BigInteger, List<PartUsageCountVO>> partUsageLinkVOMap = commonService.queryPartUsageParent(
                Collections.singletonList(oid), "direct", "0");
        List<PartUsageCountVO> partUsageCountVOS = partUsageLinkVOMap.get(oid);
        if (CollUtil.isNotEmpty(partUsageCountVOS)) {
            //通过LinkOid查询当前父级的OID
            List<BigInteger> list = partUsageCountVOS.stream().map(PartUsageCountVO::getOid).collect(Collectors.toList());
            //通过OID获取父级详情信息
            List<TyPartAllVO> tyPartAllVOS = typlmPartService.queryPartAllVOList(list);
            for (TyPartAllVO tyPartAllVO : tyPartAllVOS) {
                PartDO parebtPartDO = rtPartMapper.queryLatestPartByNumberAndView(tyPartAllVO.getObjectNumber(),
                        "Design", "");
                if (ObjectUtils.isEmpty(parebtPartDO)) {
                    continue;
                }
                PartBomTreeByFilterVO bomTreeByFilterVO = queryChildParts(parebtPartDO.getViewRef().getName(), parebtPartDO.getOid().toString(), parebtPartDO.getObjnumber(), "1", false, null);
                List<PartBomTree> partBomTreeList = bomTreeByFilterVO.getPartBomTreeList();
                if (CollUtil.isNotEmpty(partBomTreeList)) {
                    List<PartBomTree> partBomTrees = partBomTreeList.stream().filter(partBomTree -> String.valueOf(oid).equals(partBomTree.getPartoid())).collect(Collectors.toList());
                    if (CollUtil.isNotEmpty(partBomTrees)) {
                        PartBomTree partBomTree = partBomTrees.get(0);
                        //获取制造属性
                        String ibaValue = "";
                        if (ObjectUtils.isNotEmpty(partBomTree.getIbaAttributeMap().get(ibaAttrList.get("ManufacturingAttr")))) {
                            ibaValue = partBomTree.getIbaAttributeMap().get(ibaAttrList.get("ManufacturingAttr")).get(0);
                        }
                        if ("直采件".equals(ibaValue)) {
                            PartBomTreeByFilterVO bomTreeByFilterVO2 = queryChildParts(partBomTree.getView(), partBomTree.getPartoid(), partBomTree.getObjectNumber(), "N", true, null);
                            List<PartBomTree> partBomTreeList2 = bomTreeByFilterVO2.getPartBomTreeList();
                            if (CollUtil.isNotEmpty(partBomTreeList2)) {
                                treeList.addAll(partBomTreeList2);
                            }
                        } else {
                            getPartBomTreeInfo(tyPartAllVO.getOid(), ibaAttrList, treeList);
                        }
                    }
                }
            }
        }
    }

    private PartBomTreeByFilterVO queryChildParts(String view, String fatherOid, String number, String expandLevel, Boolean nestedTree, String lifeKey) {
        List<ChildPartsFiltersDTO> conditions = new ArrayList<>();
        ChildPartsFiltersDTO childPartsFiltersDTO = new ChildPartsFiltersDTO();

        childPartsFiltersDTO.setExpandCondition("latest");
        childPartsFiltersDTO.setView(view);
        if (ObjectUtils.isNotEmpty(lifeKey)) {
            childPartsFiltersDTO.setLifecycleStateKey(lifeKey);
        }
        conditions.add(childPartsFiltersDTO);
        ExpandBomTreeByFilterDTO expandBomTreeByFilterDTO = new ExpandBomTreeByFilterDTO();
        expandBomTreeByFilterDTO.setConditions(conditions);
        expandBomTreeByFilterDTO.setFatherOid(fatherOid);//设置oid
        expandBomTreeByFilterDTO.setFatherNumber(number);
        expandBomTreeByFilterDTO.setFatherOtype(TableTypeConstrant.TY_PART_OTYPE);
        expandBomTreeByFilterDTO.setExpandLevel(expandLevel);
        List<String> ibaList = new ArrayList<>();
        //入库件
        ibaList.add("ManufacturingAttr");
        expandBomTreeByFilterDTO.setIbaColumns(ibaList);
        expandBomTreeByFilterDTO.setIsQueryIBA(true);
        expandBomTreeByFilterDTO.setIsNestedTree(nestedTree);
        return this.typlmPartBomService.expandBomTreeByFilterNew(
                expandBomTreeByFilterDTO);
    }

    private Map<String, String> getIbaAttrList() {
        Map<String, String> map = new HashMap<>();
        List<StringDefDO> stringDefDOList = typlmStringDefMapper.selectAll();
        for (StringDefDO stringDefDO : stringDefDOList) {
            map.put(stringDefDO.getName(), stringDefDO.getOid().toString());
        }
        List<FloatDefDO> floatDefDOList = typlmFloatDefMapper.selectAll();
        for (FloatDefDO floatDefDO : floatDefDOList) {
            map.put(floatDefDO.getName(), floatDefDO.getOid().toString());
        }
        List<BooleanDefDO> booleanDefDOS = typlmBooleanDefMapper.selectAll();
        for (BooleanDefDO booleanDefDO : booleanDefDOS) {
            map.put(booleanDefDO.getName(), booleanDefDO.getOid().toString());
        }
        return map;
    }
}